
	<h2>Cap&iacute;tulo 7 SQL* LOADER</h2>
<br /><br />
<p class=\"definicion\" align=\"justify\">
Este programa nos permite leer ficheros en diferentes formatos e insertar los datos en nuestra base de datos. Es comando para el SQL* Loader es sqlldr. Algunos ejemplos de sintaxis de este comando son:
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
> sqlldr system/password regions.ctl
> sqlldr control=regions.ctl userid=system/password
> sqlldr system/password control=regions.ctl
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
En estos ejemplos estamos haciendo los mismo, estamos haciendo un loader conectandonos como system/password y utilizando el fichero de control regions.ctl.

La lista de parametros de configuracion que nos podemos encontrar es:
</p>
<blockquote>
- userid: El string de conexion de la base de datos SYS/oracle@ORCL.<br />
- control: El fichero de control.<br />
- log: El nombre del fichero de log.<br />
- bad: El nombre del fichero que va a almacenar los resultados que han generado un fallo al hacer el insert.<br />
- data: Nombre del fichero donde vamos a extraer los datos.<br />
- discardfile: Nombre del fichero que va a almacenar los registros que no coinciden con el patron del loader.<br />
- discardmax: Numero m&aacute;ximo de registros descartados antes de parar el loader.<br />
- load: Numero de registros a cargar.<br />
- errors: Numero de errores antes de parar el loader.<br />
- partfile: Nombre del fichero que contiene parametros adicionales.<br />
</blockquote>
<p class=\"definicion\" align=\"justify\">
<b>- FICHERO DE CONTROL.</b>
<br />
Como hemos comentado, el parametro de configuracion control almacena el nombre del fichero de control que va a definir el patron para extraer los datos del fichero de datos. Un ejemplo de este fichero es:
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
-- Control file begins with LOAD DATA
INFILE *
-- The * tells SQL*Loader the data is inline
INTO TABLE regions TRUNCATE
-- truncate the target table before loading
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"'
-- how to parse the data
(region_id, region_name)
-- positional mapping of data file fields to table columns
-- lines following BEGINDATA are loaded
-- no comments are allowed after BEGINDATA
BEGINDATA
1,\"Europe\"
2,\"Americas\"
3,\"Asia\"
4,\"Middle East and Africa\".
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Las diferentes partes que nos encontramos en este fichero son:
</p>
<blockquote>
- LOAD DATA: Indicamos a SQL* LOADER que empezamos la definicion de un nuevo proceso de carga. Si a casos tuviesemos mas procesos de carga con una estructura diferente despues de este bloque pondriamos CONTINUE LOAD DATA.
<br />
- INFILE *: Estamos diciendo que los datos a cargar se encuentran dentro del fichero de control dentro de la seccion de BEGINDATA.
<br />
- INTO TABLE regions TRUNCATE: Indicamos la tabla donde vamos a insertar los datos, indicando que previamente trunque la tabla. Podemos utiliar otra configuracion como APPEND, REPLACE or DELETE. La diferencia entre DELETE y TRUNCATE es que delete permite hacer un rollback de los datos borrados.
<br />
- FILEDS TERMINATED BY ',': Definimos el caracter que nos va a separar los diferentes campos en el loader.
<br />
- OPTIONALLY ENCLOSED BY '\"': Le decimos que quite las dobles comillas al cargar los datos.
</blockquote>
<p class=\"definicion\" align=\"justify\">
Otro ejemplo del fichero de control tenemos:
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
INFILE '/apps/seed_data/regions.dat'
BADFILE '/apps/seed_data/regions.bad'
DISCARDFILE '/apps/seed_data/regions.dsc'
OPTIONS (DIRECT=TRUE)
-- data file spec
INTO TABLE regions APPEND
-- add this data to the existing target table
(region_id POSITION(1) INTEGER EXTERNAL
,region_name POSITION(3:25) NULLIF region_name = BLANKS
) -- how to parse the data
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Las partes interesantes a comentar en este ejemplo son:
</p>
<blockquote>
- INFILE: Ahora si le damos el fichero de datos a cargar. Por lo que omitimos la seccion de BEGINDATA.
<br />
- BADFILE: Configuramos el fichero donde dejar los datos que han originado un error al hacer el insert.
<br />
- DISCARDFILE: Comfiguramos el nombre del fichero que va a lamacenar los registros que no han coincidido con el patron.
<br />
- OPTIONS (DIRECT=TRUE): Aqui estamos indicamdo que queremos utilizar direct path. La diferencia entre direct path y el metodo convencional es que mediante el metodo convenciona se utilizan INSERTs, mediante el direct path saltamos mucha de esta l&oacute;gica, llegando a ser mas rapido en determinadas situaciones. Pero tenemos algunas restricciones a la hora de utilizar directh path: Los indices se reconstruirar al final del loader, si se ha producido alguna violacion de clave privada los indices quedaran en un estado unusable. No podremos utilizar directh path si existen transacciones activas sobre la tabla destino. Si tenemos algun trigger no disparara. Por ultimo las foreign keys se desactivaran activandolas al final del loader.
<br />
- region_id POSITION(1) INTEGER EXTERNAL: Para esta columna estamo indicando que lo utilice como un entero y que coja el primer caracter.
<br />
- region_name POSITION(3:5) NULLIF region_name= BLANKS: Aqui le estamos diciendo que coja los caracteres del 3 al 5 y que inserte un NULL si ese espacio esta ocupado por espacios en blanco.
</blockquote>
<p class=\"definicion\" align=\"justify\">
Voy a poner otros ejemplo que he encontrado por ahi :-):
<br /><br />
Ejemplo1: Indicamos el nombre de las columnas donde insertar los datos, tambien indicamos que la columna empname puede aparecer limitada por comillas dobles.
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
load data
infile *
into table emp
fields terminated by \",\" optionally enclosed by '\"'
( empno, empname, sal, deptno )
beginfile
10001,\"Scott Tiger\", 1000, 40
10002,\"Frank Naude\", 500, 20
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo2: Definimos la posicion de los campos y el tipo de los mismos.
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
load data
infile *
replace
into table departments
( dept position (02:05) char(4),
deptname position (08:27) char(20)
)
begindata
COSC COMPUTER SCIENCE
ENGL ENGLISH LITERATURE
MATH MATHEMATICS
POLY POLITICAL SCIENCE
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo3: Para no cargar las cabeceras del principio del fichero
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
OPTIONS (SKIP=5)
LOAD DATA
INFILE *
INTO TABLE load_positional_data
( data1 POSITION(1:5),
data2 POSITION(6:15)
)
BEGINDATA
Cabecera 1
.
.
Cabecera 5
11AAAAAAAAAA
22BBBBBBBBBB
...
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo4: Asignamos valores a columans que no intervienen en el loader.
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
INFILE *
INTO TABLE modified_data
( rec_no \"my_db_sequence.nextval\",
region CONSTANT '31',
time_loaded \"to_char(SYSDATE, 'HH24:MI')\",
data1 POSITION(1:5) \":data1/100\",
data2 POSITION(6:15) \"upper(:data2)\",
data3 POSITION(16:22)\"to_date(:data3, 'YYMMDD')\"
)
BEGINDATA
11AAAAAAAAAA991201
22BBBBBBBBBB990
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo5: Podemos cargar datos de varios ficheros a la vez:
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
INFILE file1.dat
INFILE file2.dat
INFILE file3.dat
APPEND
INTO TABLE emp
( empno POSITION(1:4) INTEGER EXTERNAL,
ename POSITION(6:15) CHAR,
deptno POSITION(17:18) CHAR,
mgr POSITION(20:23) INTEGER EXTERNAL
)
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo6a: Podemos utilizar la clausula WHERE para condicionar los datos que se van a insertar.
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
INFILE *
INTO TABLE tab1 WHEN tab = 'tab1'
( tab FILLER CHAR(4),
col1 INTEGER
)
INTO TABLE tab2 WHEN tab = 'tab2'
( tab FILLER POSITION(1:4),
col1 INTEGER
)
BEGINDATA
tab1|1
tab1|2
tab2|2
tab3|3
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo6b:
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
INFILE 'mydata.dat' BADFILE 'mydata.bad' DISCARDFILE 'mydata.dis'
APPEND
INTO TABLE my_selective_table
WHEN (01) <> 'H' and (01) <> 'T' and (30:37) = '20031217'
(
region CONSTANT '31',
service_key POSITION(01:11) INTEGER EXTERNAL,
call_b_no POSITION(12:29) CHAR
)
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo7: Podemos insertar en varias tablas, siempre y cuando utilicemos POSITION
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
INFILE 'mydata.dat'
REPLACE
INTO TABLE emp
WHEN empno != ' '
( empno POSITION(1:4) INTEGER EXTERNAL,
ename POSITION(6:15) CHAR,
deptno POSITION(17:18) CHAR,
mgr POSITION(20:23) INTEGER EXTERNAL
)
INTO TABLE proj
WHEN projno != ' '
( projno POSITION(25:27) INTEGER EXTERNAL,
empno POSITION(1:4) INTEGER EXTERNAL
)
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo8: Combinacion ejemplos 6 y 7
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
INFILE 'mydata.dat' BADFILE 'mydata.bad' DISCARDFILE 'mydata.dis'
APPEND
INTO TABLE my_selective_table
WHEN (01) <> 'H' and (01) <> 'T'
(
region CONSTANT '31',
service_key POSITION(01:11) INTEGER EXTERNAL,
call_b_no POSITION(12:29) CHAR
)
INTO TABLE my_selective_table
WHEN (30:37) = '20031217'
(
region CONSTANT '31',
service_key POSITION(01:11) INTEGER EXTERNAL,
call_b_no POSITION(12:29) CHAR
)
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo9: Para desechar una determinada columna
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
TRUNCATE INTO TABLE T1
FIELDS TERMINATED BY ','
( field1,
field2 FILLER,
field3
)
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo10: Para desechar una determinada columna pero que utilizaremos despues
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
LOAD DATA
INFILE *
TRUNCATE INTO TABLE sometable
FIELDS TERMINATED BY \",\" trailing nullcols
(
c1,
field2 BOUNDFILLER,
field3 BOUNDFILLER,
field4 BOUNDFILLER,
field5 BOUNDFILLER,
c2 \":field2 || :field3\",
c3 \":field4 + :field5\"
)
</p></pre></blockquote>
<p class=\"definicion\" align=\"justify\">
Ejemplo11: Si el fichero de datos no tiene un formato correcto, podemos definir nosotros el delimitador que nos convenga
</p>
<blockquote style=\"COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif\"><pre><p>
load data
infile \"test.dat\" \"str '|\n'\"
into test_table
fields terminated by ';' TRAILING NULLCOLS
(
desc,
txt
)

-test.dat:
one line;hello dear world;|
two lines;Dear world,
hello!;|
</p></pre></blockquote>